<?php
/**
 * User: YL
 * Date: 2019/09/19
 */

namespace App\Common\Services;

use App\Common\Help;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use restful\ResultException;
use restful\utils\Env;
use restful\utils\FileSize;
use SplFileInfo;

class UploadService extends BaseService
{
    public function upload(Request $request)
    {
        $files = $this->validate($request);

        // 是否原始名称保存
        $isOrigin = Help::boolean($request->input('is_origin')) === true;
        // 是否返回url地址
        $isUrl = Help::boolean($request->input('is_url')) === true;

        $date = date('Ymd');
        $res = [];
        foreach ($files as $file) {
            $_path = '/' . Storage::disk('app-public')->putFileAs(
                    'uploads/' . $date,
                    $file,
                    $isOrigin ? $file->getClientOriginalName() : $file->hashName()
                );
            $res[] = $isUrl ? Help::getApiUrl($_path) : $_path;
        }

        $this->success($res);
    }

    /**
     * 验证并返回文件
     * @param Request $request
     * @return array|UploadedFile|UploadedFile[]|SplFileInfo|null
     * @throws ResultException
     */
    protected function validate(Request $request)
    {
        $file = $request->file('file');
        // 文件大小
        $size = FileSize::get(Env::get('upload.size', '10m'));

        if (! is_array($file)) {
            if (! $file instanceof SplFileInfo) {
                $this->error('文件格式不正确');
            }

            // 验证文件大小
            $this->checkSize($file, $size);

            $file = [$file];
        } else {
            foreach ($file as $v) {
                if (! $v instanceof SplFileInfo) {
                    $this->error('文件格式不正确');
                }

                // 验证文件大小
                $this->checkSize($file, $size);
            }
        }

        return $file;
    }

    /**
     * 验证文件大小
     * @param SplFileInfo $file
     * @param int $size
     * @throws ResultException
     */
    protected function checkSize(SplFileInfo $file, int $size)
    {
        if ($size < $file->getSize()) {
            $this->error(sprintf(
                '%s文件大于%s',
                $file->getClientOriginalName(),
                $size
            ));
        }
    }
}
